package util

import (
	"errors"
	"fmt"
	"github.com/nfnt/resize"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"log"
	"math"
	"os"
)

func SubImage(imageSrc string, outPath string, qw int, qh int) {
	fIn, _ := os.Open(imageSrc)
	defer fIn.Close()
	err := errors.New("unknow error")
	origin, fm, err := image.Decode(fIn)
	if err != nil {
		log.Println(err)
		return
	}
	height := origin.Bounds().Dy()
	width := origin.Bounds().Dx()
	row := int(math.Ceil(float64(height) / float64(qw)))
	clum := int(math.Ceil(float64(width) / float64(qh)))
	fmt.Println("图片大小:", width, height, "切割完毕 dst=", row, clum)
	cx := 0
	for r := row - 1; r > 0; r-- {
		for c := 0; c < clum; c++ {
			filename := fmt.Sprintf("%s\\%d_%d.jpg", outPath, cx, c)
			//filename := `${cx}_${c}.jpg`
			x := c * qw
			y := r*qh - qh
			err2 := Clip(origin, filename, fm, x, y, qw, qh, 100)
			fmt.Println("切割完毕 dst=", filename)
			if err2 != nil {
				panic(err2)
			}
		}
		cx = cx + 1
	}

}

//补上缺失的代码
//* Clip 图片裁剪
//* 入参:图片输入、输出、缩略图宽、缩略图高、Rectangle{Pt(x0, y0), Pt(x1, y1)}，精度
//* 规则:如果精度为0则精度保持不变
//*
//* 返回:error
// */
func Clip(origin image.Image, outpath string, fm string, x0, y0, x1, y1, quality int) (err error) {
	err = errors.New("unknow error")
	defer func() {
		if r := recover(); r != nil {
			log.Println(r)
		}
	}()
	fOut, _ := os.Create(outpath)
	defer fOut.Close()

	var canvas = origin
	switch fm {
	case "jpeg":
		img := canvas.(*image.YCbCr)
		subImg := img.SubImage(image.Rect(x0, y0, x1+x0, y1+y0)).(*image.YCbCr)
		return jpeg.Encode(fOut, subImg, &jpeg.Options{quality})
	case "png":
		switch canvas.(type) {
		case *image.NRGBA:
			img := canvas.(*image.NRGBA)
			subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.NRGBA)
			return png.Encode(fOut, subImg)
		case *image.RGBA:
			img := canvas.(*image.RGBA)
			subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)
			return png.Encode(fOut, subImg)
		}
	case "gif":
		img := canvas.(*image.Paletted)
		subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.Paletted)
		return gif.Encode(fOut, subImg, &gif.Options{})
	default:
		return errors.New("ERROR FORMAT")
	}
	return nil
}

func ResizeImage(srcpath string, outpath string, scale float64) {
	file, err := os.Open(srcpath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	origin, fm, err := image.Decode(file)
	if err != nil {
		log.Fatal(err)
	}
	width := origin.Bounds().Dx()  //
	height := origin.Bounds().Dy() //
	fmt.Println("图片实际宽度和高度为：",width,height)
	newWidth := float64(width) * scale
	newHeight := float64(height) * scale
	m := resize.Resize(uint(newWidth), uint(newHeight), origin, resize.Lanczos3)
	imageformat(fm,outpath,m,origin)
	fmt.Println("缩放完成后的高度和宽度为", newWidth, newHeight)
}

func imageformat(fm string, outPath string, newImage image.Image, origin image.Image) (err error) {
	fOut, err := os.Create(outPath)
	if err != nil {
		log.Fatal(err)
	}
	defer fOut.Close()
	switch fm {
	case "jpeg":
		return jpeg.Encode(fOut, newImage, nil)
	case "png":
		switch origin.(type) {
		case *image.NRGBA:

			return png.Encode(fOut, newImage)
		case *image.RGBA:

			return png.Encode(fOut, newImage)
		}
	case "gif":
		return gif.Encode(fOut, newImage, &gif.Options{})
	default:
		return errors.New("ERROR FORMAT")
	}
	return nil
}
